home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / dev / lang / SmallEiffel.lha / SmallEiffel / lib_se / reverse_assignment.e < prev    next >
Text File  |  1998-12-22  |  6KB  |  239 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  4. --                       http://www.loria.fr/SmallEiffel
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it 
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later 
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License 
  11. -- for  more  details.  You  should  have  received a copy of the GNU General 
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class REVERSE_ASSIGNMENT
  17.    --    
  18.    -- For instructions like :
  19.    --                          foo ?= bar;
  20.    --                          foo ?= bar + 1;
  21.    --
  22.  
  23. inherit INSTRUCTION;
  24.    
  25. creation make
  26.    
  27. feature 
  28.       
  29.    left_side: EXPRESSION;
  30.    
  31.    right_side: EXPRESSION;
  32.    
  33. feature {NONE}
  34.    
  35.    current_type: TYPE;
  36.    
  37. feature 
  38.       
  39.    make(ls: like left_side; rs: like right_side) is
  40.       require
  41.      ls /= Void;
  42.      rs /= Void
  43.       do
  44.      left_side := ls;
  45.      right_side := rs;
  46.       end; 
  47.  
  48. feature
  49.    
  50.    end_mark_comment: BOOLEAN is false;
  51.    
  52. feature
  53.  
  54.    use_current: BOOLEAN is
  55.       do
  56.      if left_side.use_current then
  57.         Result := true;
  58.      else
  59.         Result := right_side.use_current;
  60.      end;
  61.       end;
  62.  
  63.    afd_check is
  64.       do
  65.      right_side.afd_check;
  66.       end;
  67.  
  68.    collect_c_tmp is
  69.       do
  70.      right_side.collect_c_tmp;
  71.       end;
  72.  
  73.    compile_to_c is   
  74.       local
  75.      run: ARRAY[RUN_CLASS];
  76.      i: INTEGER;
  77.       do
  78.      if right_type.run_type.is_expanded then
  79.         eh.add_position(start_position);
  80.         fatal_error("Right-hand side expanded Not Yet Implemented.");
  81.      end;
  82.      run := left_type.run_class.running;
  83.      if run = Void then
  84.         if not right_side.can_be_dropped then
  85.            right_side.compile_to_c;
  86.            cpp.put_string(fz_00);
  87.         end;
  88.         left_side.compile_to_c;
  89.         cpp.put_string("=NULL;%N");
  90.      else
  91.         left_side.compile_to_c;
  92.         cpp.put_character('=');
  93.         if right_side.is_current then
  94.            cpp.put_string(fz_cast_t0_star);
  95.         end;
  96.         right_side.compile_to_c;
  97.         cpp.put_string(";%Nif(NULL!=(");
  98.         left_side.compile_to_c;
  99.         cpp.put_string("))switch(((T0*)");
  100.         left_side.compile_to_c;
  101.         cpp.put_string(")->");
  102.         cpp.put_string("id) {%N");
  103.         from  
  104.            i := run.lower;
  105.         until
  106.            i > run.upper
  107.         loop
  108.            cpp.put_string("case ");
  109.            cpp.put_integer(run.item(i).id);
  110.            cpp.put_string(": ");
  111.            i := i + 1;
  112.         end;
  113.         cpp.put_string("%Nbreak;%Ndefault:%N");
  114.         left_side.compile_to_c;
  115.         cpp.put_string("=NULL;%N};");
  116.      end;
  117.       end;
  118.    
  119.    compile_to_jvm is
  120.       local
  121.      run: ARRAY[RUN_CLASS];
  122.      rc: RUN_CLASS;
  123.      point1, i: INTEGER;
  124.      ca: like code_attribute;
  125.       do
  126.      ca := code_attribute;
  127.      if right_type.run_type.is_expanded then
  128.         eh.add_position(start_position);
  129.         fatal_error("Right-hand side expanded Not Yet Implemented.");
  130.      end;
  131.      run := left_type.run_class.running;
  132.      if run = Void or else run.empty then
  133.         right_side.compile_to_jvm;
  134.         ca.opcode_pop;
  135.         ca.opcode_aconst_null;
  136.         left_side.jvm_assign;
  137.      else
  138.         right_side.compile_to_jvm;
  139.         ca.opcode_dup;
  140.         point1 := ca.opcode_ifnull;
  141.         from  
  142.            ca.branches.clear;
  143.            i := run.upper;
  144.         until
  145.            i = 0
  146.         loop
  147.            ca.opcode_dup;
  148.            rc := run.item(i);
  149.            rc.opcode_instanceof;
  150.            ca.branches.add_last(ca.opcode_ifne);
  151.            i := i - 1;
  152.         end;
  153.         ca.opcode_pop;
  154.         ca.opcode_aconst_null;
  155.         ca.resolve_u2_branch(point1);
  156.         ca.resolve_branches;
  157.         left_side.jvm_assign;
  158.      end;
  159.       end;
  160.    
  161.    is_pre_computable: BOOLEAN is false;
  162.  
  163.    start_position: POSITION is
  164.       do
  165.      Result := left_side.start_position;
  166.       end;
  167.    
  168.    to_runnable(ct: TYPE): like Current is
  169.       local
  170.      e: EXPRESSION;
  171.       do
  172.      if current_type = Void then
  173.         current_type := ct;
  174.         e := left_side.to_runnable(ct);
  175.         if e = Void then
  176.            error(left_side.start_position,fz_blhsoa);
  177.         else
  178.            left_side := e;
  179.         end;
  180.         if nb_errors = 0  then
  181.            e := right_side.to_runnable(ct);
  182.            if e = Void then
  183.           error(right_side.start_position,fz_brhsoa);
  184.            else
  185.           right_side := e;
  186.            end;
  187.         end;
  188.         if nb_errors = 0 and then                                
  189.            right_type.run_type.is_a(left_type.run_type) then          
  190.            if not right_side.is_current and then
  191.           not left_type.is_like_current
  192.         then                          
  193.           eh.add_type(right_type," is a ");                       
  194.           eh.add_type(left_type,". Simple assignment is allowed");
  195.           warning(start_position," (%"?=%" is not necessary).");  
  196.            end;                                                       
  197.         end;                                                          
  198.         eh.cancel;
  199.         if not left_type.run_type.is_reference then
  200.            eh.add_type(left_type.run_type," is not a reference Type.");
  201.            error(start_position," Invalid reverse assignment (VJRV).");
  202.         end;
  203.         if nb_errors = 0 then
  204.            Result := Current;
  205.         end;
  206.      else
  207.         !!Result.make(left_side,right_side);
  208.         Result := Result.to_runnable(ct);
  209.      end;
  210.       end;
  211.    
  212.    right_type: TYPE is
  213.       do
  214.      Result := right_side.result_type;
  215.       ensure
  216.      Result /= Void
  217.       end;
  218.    
  219.    left_type: TYPE is
  220.       do
  221.      Result := left_side.result_type;
  222.       ensure
  223.      Result /= Void
  224.       end;
  225.    
  226.    pretty_print is
  227.       do
  228.      pretty_print_assignment(left_side,"?=",right_side);
  229.       end;
  230.    
  231. invariant
  232.    
  233.    left_side.is_writable;
  234.    
  235.    right_side /= Void;
  236.    
  237. end -- REVERSE_ASSIGNMENT
  238.  
  239.